相关类
LauncherSwipeHandlerV2 <- BaseSwipeUpHandlerV2
一个和手势相关的重要的类,它主要处理手势导航相关的操作,后面有一篇文章来专门介绍这个类。maybeUpdateRecentsAttachedState()方法判断显示或者隐藏多任务- ShelfPeekAnim 用来处理多任务 HIDE, PEEK, and OVERVIEW 状态之间切换时的动画
- InputConsumer 事件消费者,有多种实现类,会根据系统处于不同的状态而生成不同的事件处理器,后面代码会详细介绍。
- RecentsView RecentsView 有两个子类,一个是 LauncherRecentsView,一个是 FallbackRecentsView,FallbackRecentsView 显示在 RecentsActivity 中,用在多任务作为一个单独的 Activity 运行的场景,比如简易模式情况下。
QuickstepAppTransitionManagerImpl <- LauncherAppTransitionManager
管理打开和关闭App时切换操作,比如设置切换动画等。- TaskViewSimulator 一个模拟TaskView 和 RecentsView 的工具类,当我们在应用界面上划启动多任务时,有一个跟随手指移动的卡片,这个卡片就是这个类模拟出来的TaskView。
- TaskView 多任务里面的一个卡片
- TaskThumbnailView 任务卡片里面的界面截图
- MotionPauseDetector 检测手势暂停
手势启动流程
通过手势启动多任务时,SystemUI会把触摸事件传递给TouchInteractionService.onInputEvent
来处理,TouchInteractionService
会交由合适的InputConsumer
来处理,我们这里就介绍由其他应用界面启动时的OtherActivityInputConsumer
。然后,事件将有两个比较重要的处理节点,一个是通过PagedView.onTouchEvent
来处理,然后再由OtherActivityInputConsumer
自己来处理。
从应用界面启动多任务,首先是处理当前window做位移和缩放,然后在合适的时机显示多任务卡片。
下面是事件的一个简单处理流程:
1 | TouchInteractionService.onInputEvent |
1 | // TouchInteractionService.java |
在 TouchInteractionService.onInputEvent 中会初始化 InputConsumer 事件消费者,有多种实现类,会根据系统处于不同的状态而生成不同的事件处理器。
- DelegateInputConsumer:抽象类
- AssistantInputConsumer:语音助手消费事件
- OverscrollInputConsumer:
- DeviceLockedInputConsumer:
- OtherActivityInputConsumer:非桌面情况下启动多任务的事件消费者
- OverviewInputConsumer:在桌面或者最近任务界面处理事件的消费者
- OverviewWithoutFocusInputConsumer:
- ResetGestureInputConsumer:
- ScreenPinnedInputConsumer:
- SysUiOverlayInputConsumer:
启动桌面
调用 ActivityManagerWrapper.getInstance().startRecentsActivity 去启动多任务activity,这里也就是桌面activity
1 | mCallbacks = new RecentsAnimationCallbacks(activityInterface.allowMinimizeSplitScreen()); |
1 | Launcher.onStart |
多任务的显示:
Launcher.onStart->WindowTransformSwipeHandler.onLauncherStart->LauncherActivityControllerHelper.prepareRecentsUI->LauncherStateManager.goToState->RecentsViewStateController.setState->BaseRecentsViewStateController.setState->RecentsView.CONTENT_ALPHA.setValue -> RecentsView.setContentAlpha -> setVisibility
## 注册状态回调
当调用 mStateCallback.setState 切换状态时会执行相关的回调函数,这部分在BaseSwipeUpHandlerV2中详细介绍。
准备多任务UI
prepareRecentsUI() 返回AnimationFactory,提供显示多任务的动画,并显示多任务
1 | // LauncherActivityInterface.java |
1 | LauncherActivityInterface.prepareRecentsUI // 返回AnimationFactory,提供显示多任务的动画 |
多任务显示和隐藏的动画
多任务显示和隐藏的时机一个是调用maybeUpdateRecentsAttachedState来实现,它有两个重载的方法,它决定何时隐藏或者显示RecentsView,滑动过程中,会根据滑动的距离和速度来决定是只显示当前滑动图片或者是显示多任务,而且显示和隐藏多任务过程中可能要有切换动画,在滑动过程中,可能会切换小窗模式,这些时候都就要判断是否隐藏或者显示多任务。
另外一个是在滑动卡片结束时或者在桌面界面上划手势结束时会启动显示多任务的逻辑。
1 | BaseSwipeUpHandlerV2.maybeUpdateRecentsAttachedState // 显示或者隐藏多任务 |
1 | // BaseSwipeUpHandlerV2.java |
1 | // BaseActivityInterface.java |
在其他应用界面,滑动手势结束时:
1 | AnimationSuccessListener.onAnimationEnd() |
在桌面时滑动手势结束时:
1 | FlingAndHoldTouchController.goToOverviewOnDragEnd.onAnimationEnd() |
多任务缩放和位置
手势在滑动过程中多任务的缩放和位置由 BaseSwipeUpHandlerV2.updateFinalShift()
进行,具体介绍在 BaseSwipeUpHandlerV2。
快切
在滑动屏幕下方的一块区域时,会快速切换应用,其实这个还是多任务 RecentsView 的全屏切换,切换完成后再启动对应的应用。
快切操作主要时通过RecentsView的切换来完成的,然后在启动目标TaskView,事件的处理通过 CachedEventDispatcher.dispatchEvent 分发到 PagedView.onTouchEvent 处理。
OtherActivityInputConsumer.onMotionEvent -> CachedEventDispatcher.dispatchEvent -> RecentsView.getEventDispatcher.accept -> PagedView.onTouchEvent ->MotionEvent.ACTION_MOVE -> PortraitPagedViewHandler.set -> View::scrollBy
推荐文章
Android R中虚拟按键的详细设计与实现 https://blog.csdn.net/chen364567628/article/details/107525744
走近Android -R 11 手势的详细设计与实现源码分析 https://blog.csdn.net/chen364567628/article/details/109126604